package org.dreamwork.jasmine2.web.controls.chart.format;

import org.dreamwork.jasmine2.util.StringConverter;
import org.dreamwork.jasmine2.web.controls.chart.ChartContext;
import org.dreamwork.peony.DataBinder;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 * User: seth
 * Date: 2010-5-12
 * Time: 10:15:37
 */
public class LineDataFormat implements IChartDataFormat {
    public String format (List<?> data, ChartContext context) {
        String valueField = (String) context.getParameter ("valueField");
        String textField = (String) context.getParameter ("textField");
        String categoryField = (String) context.getParameter ("categoryField");
        String categoryColorField = (String) context.getParameter ("categoryColorField");
        String url = (String) context.getParameter("url");
        List<String> urlParamN = new ArrayList<String> ();

        if (!StringConverter.isEmpty(url)) {
            while (url.contains("{")) {
                String s = url.substring(url.indexOf('{') + 1, url.indexOf('}'));
                url = url.replace("{" + s + "}", "%s");
                urlParamN.add(s);
            }
        }

        Map<String, List<Object>> categories = new HashMap<String, List<Object>> ();
        Map<String, String> categoryColors = new HashMap<String, String> ();
        Map<String, Integer> serials = new HashMap<String, Integer> ();
        List<String> set = new ArrayList<String> ();

        for (Object container : data) {
            String serial = (String) DataBinder.eval (container, textField);
            if (!set.contains (serial)) set.add (serial);
            String category = (String) DataBinder.eval (container, categoryField);
            List<Object> temp = categories.get (category);
            if (temp == null) {
                temp = new ArrayList<Object> ();
                categories.put (category, temp);
            }
            temp.add (container);
            String categoryColor = null;
            if (!StringConverter.isEmpty (categoryColorField))
                categoryColor = (String) DataBinder.eval (container, categoryColorField);
            if (!StringConverter.isEmpty (categoryColor))
                categoryColors.put (category, categoryColor);
        }
        StringBuilder builder = new StringBuilder ("<?xml version=\"1.0\" encoding=\"utf-8\"?>").append ("<chart>");
        builder.append ("<series>");
        for (int i = 0; i < set.size (); i ++) {
            serials.put (set.get(i), i);
            builder.append ("<value xid=\"").append (i).append ("\">").append (set.get(i)).append ("</value>");
        }
        builder.append ("</series>");
        builder.append ("<graphs>");
        int index = 1;
        for (String key : categories.keySet ()) {
            builder.append ("<graph gid=\"").append (index).append ("\" title=\"").append (key).append ("\"");
            if (categoryColors.containsKey (key)) builder.append (" color=\"").append (categoryColors.get (key)).append ('"');
            builder.append ('>');
            List<Object> list = categories.get (key);
            for (Object o : list) {
                String text = (String) DataBinder.eval (o, textField);
                Object value = DataBinder.eval (o, valueField);
                int serial = serials.get (text);
                builder.append ("<value xid=\"").append (serial).append("\"");
                if (!StringConverter.isEmpty(url)) {
                Object[] urlParamV = new Object[urlParamN.size()];
                for (int i = 0; i < urlParamN.size(); i++) {
                    urlParamV[i] = DataBinder.eval(o, urlParamN.get(i));
                }
                builder.append(" url=\"").append(String.format(url, urlParamV)).append("\"");
            }
                builder.append (">").append (value).append ("</value>");
            }
            builder.append ("</graph>");
            index ++;
        }
        builder.append ("</graphs>");
        builder.append ("</chart>");
        return builder.toString ();
    }
}